package nsqp

import (
	"bgs/cache/redisImp"
	"bgs/conf"
	"bgs/db"
	"bgs/grpc/client"
	"bgs/grpc/imp/enums"
	handlers "bgs/nsqp/handlers/wxpay"
	"bgs/nsqp/topic"
	"bgs/nsqp/util"
	activityService "bgs/service/activity"
	afterSaleService "bgs/service/afterSale"
	brandService "bgs/service/brand"
	ledgerService "bgs/service/ledger"
	orderService "bgs/service/order"
	paymentService "bgs/service/payment"
	spokesmanService "bgs/service/spokesman"
	storeService "bgs/service/store"
	userService "bgs/service/user"
	wxpMinaService "bgs/wxp/mina"
	"github.com/nsqio/go-nsq"
	"go.uber.org/zap"
)

// const (
// topicOfTradePayed     = "trade_payed"     //支付通知
// topicOfRefundNotify   = "refund_notify"   // 退款通知
// topicOfProfitOrder    = "profit_order"    // 分账通知
// topicOfProfitReturn   = "profit_return"   // 分账回退通知
// topicOfApplyNotify    = "apply_notify"    // 进件结果通知
// topicOfWithdrawNotify = "withdraw_notify" // 二级商户提现通知
// topicOfTransferNotify = "transfer_notify" // 批量转账(到用户零钱)通知
// )

// func makeWxpayTopic(topic string) string {
// 	return fmt.Sprintf("%s-%s", enums.APPIDWXPAY, topic)
// }

// WxpayProxy proxy wxpay nsq message
type WxpayProxy struct {
	slog *zap.SugaredLogger
	subs []*nsq.Consumer
}

// NewWxpayProxy initialization
func NewWxpayProxy(
	nsqConf conf.NsqSection,
	pgdao *db.PgDao,
	slog *zap.SugaredLogger,
	vars *conf.VarsSection,
	clientProxy *client.GrpcClientProxy,
	adp *cache.Adapter,
	failover *util.NsqFailover,
	activityService *activityService.ActivityServiceImp,
	afterSaleService *afterSaleService.AfterSaleServiceImp,
	brandService *brandService.BrandServiceImp,
	ledgerService *ledgerService.LedgerServiceImp,
	orderService *orderService.OrderServiceImp,
	paymentService *paymentService.PaymentServiceImp,
	spokesmanService *spokesmanService.SpokesmanServiceImp,
	storeService *storeService.StoreServiceImp,
	userService *userService.UserServiceImp,
	wxpMinaService *wxpMinaService.MinaServiceImp,
) (proxy *WxpayProxy, err error) {
	proxy = &WxpayProxy{
		slog: slog.With("module", "WxpayProxy"),
	}
	config := nsq.NewConfig()
	config.MaxInFlight = 2

	// wxpayApplymentConsumer
	wxpayApplymentConsumerTopic := topic.Make(enums.APPIDWXPAY)(topic.ApplyNotify)
	wxpayApplymentConsumer, err := nsq.NewConsumer(wxpayApplymentConsumerTopic, appID, config)
	if err != nil {
		return
	}
	wxpayApplymentConsumer.SetLogger(
		nsqLogger,
		nsq.LogLevelError,
	)
	wxpayApplymentConsumer.AddHandler(handlers.NewApplymentHandler(pgdao, proxy.slog, wxpayApplymentConsumerTopic, failover, brandService))
	err = wxpayApplymentConsumer.ConnectToNSQLookupd(nsqConf.NsqLookupds[0])
	if err != nil {
		return
	}
	proxy.subs = append(proxy.subs, wxpayApplymentConsumer)

	// tradePayedConsumer
	tradePayedConsumerTopic := topic.Make(enums.APPIDWXPAY)(topic.TradePayed)
	tradePayedConsumer, err := nsq.NewConsumer(tradePayedConsumerTopic, appID, config)
	if err != nil {
		return
	}
	tradePayedConsumer.SetLogger(
		nsqLogger,
		nsq.LogLevelError,
	)
	tradePayedConsumer.AddHandler(handlers.NewTradePayedHandler(pgdao, proxy.slog, tradePayedConsumerTopic, failover,
		activityService, brandService,
		ledgerService, orderService,
		paymentService, spokesmanService, userService))
	err = tradePayedConsumer.ConnectToNSQLookupd(nsqConf.NsqLookupds[0])
	if err != nil {
		return
	}
	proxy.subs = append(proxy.subs, tradePayedConsumer)

	// refundedConsumer
	refundedComsumerTopic := topic.Make(enums.APPIDWXPAY)(topic.RefundNotify)
	refundedConsumer, err := nsq.NewConsumer(refundedComsumerTopic, appID, config)
	if err != nil {
		return
	}
	refundedConsumer.SetLogger(
		nsqLogger,
		nsq.LogLevelError,
	)
	refundedConsumer.AddHandler(handlers.NewRefundedHandler(pgdao, proxy.slog, refundedComsumerTopic, failover,
		activityService, afterSaleService,
		brandService, ledgerService, orderService,
		paymentService, wxpMinaService))
	err = refundedConsumer.ConnectToNSQLookupd(nsqConf.NsqLookupds[0])
	if err != nil {
		return
	}
	proxy.subs = append(proxy.subs, refundedConsumer)

	// profitOrderConsumer
	profitOrderConsumerTopic := topic.Make(enums.APPIDWXPAY)(topic.ProfitOrder)
	profitOrderConsumer, err := nsq.NewConsumer(profitOrderConsumerTopic, appID, config)
	if err != nil {
		return
	}
	profitOrderConsumer.SetLogger(
		nsqLogger,
		nsq.LogLevelError,
	)
	profitOrderConsumer.AddHandler(handlers.NewProfitOrderHandler(pgdao, proxy.slog, profitOrderConsumerTopic, failover,
		brandService, ledgerService, orderService, storeService, userService))
	err = profitOrderConsumer.ConnectToNSQLookupd(nsqConf.NsqLookupds[0])
	if err != nil {
		return
	}
	proxy.subs = append(proxy.subs, profitOrderConsumer)

	// profitReturnConsumer
	profitReturnConsumerTopic := topic.Make(enums.APPIDWXPAY)(topic.ProfitReturn)
	profitReturnConsumer, err := nsq.NewConsumer(profitReturnConsumerTopic, appID, config)
	if err != nil {
		return
	}
	profitReturnConsumer.SetLogger(
		nsqLogger,
		nsq.LogLevelError,
	)
	profitReturnConsumer.AddHandler(handlers.NewProfitReturnHandler(pgdao, proxy.slog, profitReturnConsumerTopic, failover,
		afterSaleService, brandService,
		ledgerService, paymentService, storeService, userService))
	err = profitReturnConsumer.ConnectToNSQLookupd(nsqConf.NsqLookupds[0])
	if err != nil {
		return
	}
	proxy.subs = append(proxy.subs, profitReturnConsumer)

	// brandWithdrawConsumer
	brandWithdrawConsumerTopic := topic.Make(enums.APPIDWXPAY)(topic.WithdrawNotify)
	brandWithdrawConsumer, err := nsq.NewConsumer(brandWithdrawConsumerTopic, appID, config)
	if err != nil {
		return
	}
	brandWithdrawConsumer.SetLogger(
		nsqLogger,
		nsq.LogLevelError,
	)
	brandWithdrawConsumer.AddHandler(handlers.NewBrandWithdrawHandler(pgdao, proxy.slog, brandService))
	err = brandWithdrawConsumer.ConnectToNSQLookupd(nsqConf.NsqLookupds[0])
	if err != nil {
		return
	}
	proxy.subs = append(proxy.subs, brandWithdrawConsumer)

	// userBatchTransferConsumer
	userBatchTransferConsumerTopic := topic.Make(enums.APPIDWXPAY)(topic.TransferNotify)
	userBatchTransferConsumer, err := nsq.NewConsumer(userBatchTransferConsumerTopic, appID, config)
	if err != nil {
		return
	}
	userBatchTransferConsumer.SetLogger(
		nsqLogger,
		nsq.LogLevelError,
	)
	userBatchTransferConsumer.AddHandler(handlers.NewUserBatchTransferHandler(pgdao, proxy.slog, userService))
	err = userBatchTransferConsumer.ConnectToNSQLookupd(nsqConf.NsqLookupds[0])
	if err != nil {
		return
	}
	proxy.subs = append(proxy.subs, userBatchTransferConsumer)

	// Gracefully stop the consumer.
	// consumer.Stop()

	return
}
